package com.mine.modules.vm.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.toolkit.Db;
import com.mine.common.config.exception.MineBootException;
import com.mine.common.domain.vo.Result;
import com.mine.common.utils.AnnotationUtil;
import com.mine.modules.vm.common.constant.BizConstant;
import com.mine.modules.vm.domain.dto.AddElementDto;
import com.mine.modules.vm.domain.dto.BindingSensorPointDto;
import com.mine.modules.vm.domain.dto.CommonElementListDto;
import com.mine.modules.vm.domain.dto.QueryElementDto;
import com.mine.modules.vm.domain.query.PointPageQuery;
import com.mine.modules.vm.entity.*;
import com.mine.modules.vm.mapper.VmPointMapper;
import com.mine.modules.vm.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author author
 * @since 2025-04-09
 */
@Slf4j
@Service
public class VmPointServiceImpl extends ServiceImpl<VmPointMapper, VmPoint> implements IVmPointService, IVmBaseService {

    @Resource
    private VmPointMapper vmPointMapper;

    @Resource
    private IVmLayerElementService vmLayerElementService;

    @Resource
    private IVmLayerService vmLayerService;

    @Resource
    private IVmSensorPointService vmSensorPointService;

    @Override
    public Result<?> queryPageList(PointPageQuery pointPageQuery) {
        LambdaQueryWrapper<VmPoint> queryWrapper = new LambdaQueryWrapper<>();
        if (StringUtils.isNotBlank(pointPageQuery.getPointClassify())) {
            queryWrapper.eq(VmPoint::getPointClassify, pointPageQuery.getPointClassify());
        }
        if (StringUtils.isNotBlank(pointPageQuery.getKeywords())) {
            queryWrapper.and(wrapper -> wrapper
                    .like(VmPoint::getPointName, pointPageQuery.getKeywords())
                    .or()
                    .like(VmPoint::getLabelName, pointPageQuery.getKeywords())
                    .or()
                    .like(VmPoint::getPointCode, pointPageQuery.getKeywords())
            );
        }
        if (StringUtils.isNotBlank(pointPageQuery.getLayerId())) {
            //查询所有子项id集合
            List<String> layerIds = vmLayerService.getAllSubIdsByParentId(pointPageQuery.getLayerId());
            Page<VmPoint> page = new Page<>(pointPageQuery.getPageNo(), pointPageQuery.getPageSize());
            IPage<VmPoint> pageList = vmPointMapper.selectPageWithElement(
                    page,
                    layerIds,
                    pointPageQuery.getKeywords(),
                    pointPageQuery.getPointClassify()
            );
            return Result.ok(pageList);
        } else {
            Page<VmPoint> page = new Page<>(pointPageQuery.getPageNo(), pointPageQuery.getPageSize());
            IPage<VmPoint> pageList = this.page(page, queryWrapper);
            return Result.ok(pageList);
        }
    }

    @Override
    public Result<?> addOrEdit(VmPoint vmPoint) {
        if (vmPoint == null || StringUtils.isBlank(vmPoint.getPointName())) {
            return Result.error("参数必填！");
        }
        if (vmPoint.getId() == null) {
            if (StringUtils.isBlank(vmPoint.getPointClassify())) {
                vmPoint.setPointClassify(BizConstant.POINT_CLASSIFY_REAL_MONITOR);
            }
            if (this.save(vmPoint)) {
                if (StringUtils.isNotBlank(vmPoint.getLayerId())) {
                    vmLayerElementService.addElement(new AddElementDto(
                            vmPoint.getLayerId(),
                            vmPoint.getId(),
                            vmPoint.getPointCode(),
                            vmPoint.getPointName(),
                            BizConstant.SCENE_ELEMENT_TYPE_POINT
                    ));
                }
                return Result.OK("添加成功！");
            } else {
                return Result.error("添加失败！");
            }
        } else {
            VmPoint existingAsset = this.getById(vmPoint.getId());
            if (existingAsset == null) {
                return Result.error("数据不存在，请刷新重试！");
            }
            this.updateById(vmPoint);
        }
        return Result.ok("操作成功！");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<?> delete(String id) {
        try {
            if (this.removeById(id)) {
                //删除图元表数据
                Db.lambdaUpdate(VmLayerElement.class)
                        .eq(VmLayerElement::getElementId, id)
                        .eq(VmLayerElement::getElementType, BizConstant.SCENE_ELEMENT_TYPE_POINT)
                        .remove();
                //删除传感器关联表
                Db.lambdaUpdate(VmSensorPoint.class).eq(VmSensorPoint::getPointId, id).remove();
            }
            return Result.OK("删除成功!");
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return Result.error(e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<?> deleteBatch(String ids) {
        try {
            String[] arr = ids.split(",");
            for (String id : arr) {
                if (StringUtils.isNotBlank(id)) {
                    try {
                        this.delete(id);
                    } catch (MineBootException e) {
                        if (e.getMessage() != null && e.getMessage().contains("未找到数据")) {
                            log.warn(e.getMessage());
                        } else {
                            throw e;
                        }
                    }
                }
            }
            return Result.OK("删除成功!");
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return Result.error("删除失败!");
        }
    }

    @Override
    public Result<?> getDetailsById(String id) {
        VmPoint vmPoint = this.getById(id);
        if(vmPoint == null){
            return Result.error("数据不存在，请刷新重试！");
        }
        return Result.ok(vmPoint);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<?> batchBindingSensorByPointId(BindingSensorPointDto bindingSensor) {
        if (StringUtils.isEmpty(bindingSensor.getPointId()) || StringUtils.isEmpty(bindingSensor.getSensorIds())) {
            return Result.error("参数不完整！");
        }
        try {
            String[] ids = bindingSensor.getSensorIds().split(",");
            List<VmSensorPoint> rows = Collections.emptyList();
            for (String sensorId : ids) {
                rows = new ArrayList<>();
                rows.add(new VmSensorPoint(bindingSensor.getPointId(), sensorId));
                vmSensorPointService.saveBatch(rows);
            }
        } catch (Exception e) {
            log.error(e.getMessage());
            throw new MineBootException("保存失败{" + e.getMessage() + "}");
        }
        return Result.ok("保存成功！");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<?> batchDeleteSensorByPointId(BindingSensorPointDto bindingSensor) {
        if (StringUtils.isEmpty(bindingSensor.getPointId()) || StringUtils.isEmpty(bindingSensor.getSensorIds())) {
            return Result.error("参数不完整！");
        }
        try {
            List<String> sensorIds = Arrays.asList(bindingSensor.getSensorIds().split(","));
            List<String> ids = this.vmSensorPointService.lambdaQuery()
                    .eq(VmSensorPoint::getPointId, bindingSensor.getPointId())
                    .in(VmSensorPoint::getSensorId, sensorIds)
                    .list()
                    .stream()
                    .map(VmSensorPoint::getId)
                    .collect(Collectors.toList());
            vmSensorPointService.removeBatchByIds(ids);
        } catch (Exception e) {
            log.error(e.getMessage());
            return Result.error("删除失败{" + e.getMessage() + "}");
        }
        return Result.ok("删除成功！");
    }

    @Override
    public Object basePageList(CommonElementListDto commonElementListDto) {
        QueryWrapper<VmPoint> queryWrapper = new QueryWrapper<>();
        try {
            if (StringUtils.isNotBlank(commonElementListDto.getKeywords())) {
                queryWrapper = AnnotationUtil.processCommonSearchKeywords(queryWrapper, VmPoint.class, commonElementListDto.getKeywords());
            }
            if (StringUtils.isNotBlank(commonElementListDto.getPointClassify())) {
                queryWrapper = AnnotationUtil.processCommonSearchAnd(queryWrapper, VmPoint.class, commonElementListDto.getPointClassify());
            }
            List<String> ids = vmLayerElementService.getElementIdsByLayerIdOrType(commonElementListDto.getLayerId(), commonElementListDto.getElementType());
            queryWrapper.notIn(!ids.isEmpty(), "id", ids);
            Page<VmPoint> page = new Page<>(commonElementListDto.getPageNo(), commonElementListDto.getPageSize());
            System.out.println("Query Wrapper SQL: " + queryWrapper.getSqlSegment());
            log.info("Query Wrapper SQL: {}", queryWrapper.getSqlSegment());
            return this.page(page, queryWrapper);
        } catch (Exception e) {
            log.error(e.getMessage());
            throw new RuntimeException(e);
        }
    }

    @Override
    public List<?> baseList(CommonElementListDto commonElementListDto) {
        QueryWrapper<VmPoint> queryWrapper = new QueryWrapper<>();
        try {
            if (StringUtils.isNotBlank(commonElementListDto.getKeywords())) {
                queryWrapper = AnnotationUtil.processCommonSearchKeywords(queryWrapper, VmPoint.class, commonElementListDto.getKeywords());
            }
            if (StringUtils.isNotBlank(commonElementListDto.getPointClassify())) {
                queryWrapper = AnnotationUtil.processCommonSearchAnd(queryWrapper, VmPoint.class, commonElementListDto.getPointClassify());
            }
            return this.list(queryWrapper);
        } catch (Exception e) {
            log.error(e.getMessage());
            throw new RuntimeException(e);
        }
    }

    @Override
    public List<?> baseList(QueryElementDto queryElementDto) {
        QueryWrapper<VmPoint> queryWrapper = new QueryWrapper<>();
        try {
            if (StringUtils.isNotBlank(queryElementDto.getKeywords())) {
                queryWrapper = AnnotationUtil.processCommonSearchKeywords(queryWrapper, VmPoint.class, queryElementDto.getKeywords());
            }
            if (StringUtils.isNotBlank(queryElementDto.getPointClassify())) {
                queryWrapper = AnnotationUtil.processCommonSearchAnd(queryWrapper, VmPoint.class, queryElementDto.getPointClassify());
            }
            if (queryElementDto.getElementIds() != null && !queryElementDto.getElementIds().isEmpty()) {
                queryWrapper.in("id", queryElementDto.getElementIds());
            }
            return this.list(queryWrapper);
        } catch (Exception e) {
            log.error(e.getMessage());
            throw new RuntimeException(e);
        }
    }

    @Override
    public Object getObjectById(String id) {
        return this.getById(id);
    }

    @Override
    public Result<?> setAngleView(String id, String angleView) {
        VmPoint vmPoint = this.getById(id);
        if (vmPoint == null) {
            return Result.error("数据不存在，请刷新重试！");
        }
        vmPoint.setAngleView(angleView);
        if (this.updateById(vmPoint)) {
            return Result.ok("更新成功！");
        } else {
            return Result.error("更新失败！");
        }
    }
}
